package com.hsyt.pfc.core.queue;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.IntStream;

/**
 * @Description:
 * @ClassName: WaitingQueueManager
 * @Package: com.hsyt.pfc.core.queue
 * @Author: wangze@hsyuntai.com
 * @Date: 2018年9月30日 9:59
 * @Copyright: 版权归 HSYUNTAI 所有
 */
public class WaitingQueueManager {

    private static final Logger LOGGER = LoggerFactory.getLogger(WaitingQueueManager.class);

    private static List<WaitingQueue> queues;
    private static int capacity = 5;

    private volatile int status;
    private static final int STATUS_NEW = 0;
    private static final int STATUS_ON_EXECUTE = 1;

    public WaitingQueueManager() {
        status = STATUS_NEW;
    }

    public static void createTask(Object target, String method, Object... args) {
        try {
            int index = (Math.abs(Objects.hash(target, method, args)) % capacity);
            WaitingQueue waitingQueue = queues.get(index);
            waitingQueue.createTask(target, method, args);
        } catch (InterruptedException e) {
            LOGGER.error("创建等待队列任务失败,target：{} , method: {}, args: {} ,error: {}", target, method, args, e);
        }
    }

    public static void createTask(WaitingQueueTask task) {
        try {
            int index = (Math.abs(task.hashCode()) % capacity);
            WaitingQueue waitingQueue = queues.get(index);
            waitingQueue.createTask(task);
        } catch (InterruptedException e) {
            LOGGER.error("创建等待队列任务失败,target：{} , method: {}, args: {} ,error: {}", task.getTarget(),
                    task.getMethod(), task.getParamters(), e);
        }
    }


    public synchronized void initQueue() {
        queues = new ArrayList<>(capacity);
        if (status == STATUS_NEW) {
            IntStream.range(0, capacity).forEach(index -> {
                WaitingQueue waitingQueue = new WaitingQueue();
                new Thread(waitingQueue, "WaitingThread-" + index).start();
                queues.add(waitingQueue);
            });
            status = STATUS_ON_EXECUTE;
        } else {
            LOGGER.error("waitingQueueManager already on running!");
        }
    }

    public void setCapacity(int capacity) {
        WaitingQueueManager.capacity = capacity;
    }
}
